package com.x2.modular.export.action;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.x2.base.pojo.page.LayuiPageInfo;
import com.x2.core.util.DateUtils;
import com.x2.modular.export.kit.DataUtil;
import com.x2.modular.export.kit.FetchManager;
import com.x2.modular.export.kit.IFetch;
import com.x2.modular.export.vo.XyExportExcelItem;
import com.x2.modular.export.vo.XyExportExcelRow;
import com.x2.modular.export.vo.XyExportVO;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.ByteArrayOutputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XyExportRun3 implements XyExportRun<XyExportVO> {
    private LayuiPageInfo pageInfo;
    private XyExportVO defVO;

    /**
     * 初始化
     *
     * @param inData
     * @param inDefVO
     */
    public XyExportRun3(LayuiPageInfo inData, XyExportVO inDefVO) {
        this.pageInfo = inData;
        this.defVO = inDefVO;
    }

    /**
     * 运行
     *
     * @return
     * @throws Exception
     */
    public XyExportVO call() throws Exception {
        try {

            String templatePath = "./excel/" + defVO.getModule() + "/" + defVO.getFileName() + ".xlsx";
            TemplateExportParams params = new TemplateExportParams(templatePath);
            Map<String, Object> excelMap = new HashMap<>();
            LocalDate now = LocalDate.now();
            excelMap.put("nowYear", now.getYear());
            excelMap.put("nowMonth", now.getMonth());
            excelMap.put("nowDay", now.getDayOfMonth());
            excelMap.put("nowDate", DateUtils.getDate());
            if (defVO.getExtInfo() != null) {
                excelMap.putAll(defVO.getExtInfo());
            }
            List<XyExportExcelItem> itemList = this.getCodeList();
            if (itemList.size() > 0) {
                excelMap.put("dataList", getData(pageInfo.getData(), itemList));
            } else {
                excelMap.put("dataList", pageInfo.getData());
            }
            // 基于模板导出Excel
            Workbook workbook = ExcelExportUtil.exportExcel(params, excelMap);
            ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
            workbook.write(fileOut);
            fileOut.flush();
            defVO.setFileData(fileOut.toByteArray());
            return defVO;
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        } finally {
            System.gc();
        }

    }

    /**
     * 初始化数据
     *
     * @return
     * @throws Exception
     */
    private List<Map<String, Object>> getData(List dataList, List<XyExportExcelItem> itemList) throws Exception {
        //主表数据
        List<Map<String, Object>> dataResList = new ArrayList<>();
        //卫语句
        if (dataList.size() <= 0) {
            return dataResList;
        }
        //取得需要反射的所有方法
        Object itemObject = dataList.get(0);
        //方法
        FetchManager fetchManager = new FetchManager(itemObject);
        Map<String, IFetch> methodMap = new HashMap<>();
        for (XyExportExcelItem item : itemList) {
            methodMap.put(item.getCode(), fetchManager.method(item.getCode()));
        }
        Map<String, Object> newItemMap;
        Object value;
        int rowIndex = 1;
        for (Object dataItem : dataList) {
            newItemMap = new HashMap<>();
            newItemMap.put("xh", rowIndex++);
            for (XyExportExcelItem item : itemList) {
                IFetch m = methodMap.get(item.getCode());
                if (m == null) {
                    newItemMap.put(item.getCode(), "");
                } else {
                    value = m.getValue(dataItem);
                    newItemMap.put(item.getCode(), DataUtil.changeValue(item, value));
                }
            }
            dataResList.add(newItemMap);
        }
        return dataResList;
    }


    /**
     * 取得属性列表
     */
    private List<XyExportExcelItem> getCodeList() {
        List<XyExportExcelItem> resList = new ArrayList<>();
        List<XyExportExcelRow> rowList = this.defVO.getTitle().getRowList();
        if (rowList != null) {
            for (XyExportExcelRow row : rowList) {
                if (row.getItemList() == null) {
                    continue;
                }
                for (XyExportExcelItem item : row.getItemList()) {
                    if (item.getCode() == null) {
                        continue;
                    }
                    resList.add(item);
                }
            }
        }
        return resList;
    }

}
